package com.googlecode.restitory.gae.rhino;

import java.io.CharArrayReader;
import java.io.IOException;
import java.net.URL;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;

import com.googlecode.mycontainer.commons.io.IOUtil;
import com.googlecode.restitory.gae.Request;
import com.googlecode.restitory.gae.Response;
import com.googlecode.restitory.gae.Type;
import com.googlecode.restitory.gae.hook.Chain;
import com.googlecode.restitory.gae.hook.Hook;

public class RhinoHook implements Hook {

	@Override
	public Response execute(Request request, Chain chain) {
		Response resp = chain.copy().execute(new Request(Type.GET, "/hook.js"));
		if (resp.getCode() != 200) {
			return chain.execute(request);
		}

		Context ctx = Context.enter();
		try {
			ScriptableObject scope = ctx.initStandardObjects();
			RhinoLog.config(scope, ctx);
			RhinoUtil.config(scope);
			RhinoRepo.config(scope, ctx);

			URL hook = getClass().getResource("hook.js");
			char[] chars = IOUtil.readChars(hook);
			Function f = (Function) ctx.evaluateReader(scope, new CharArrayReader(chars), hook.toString(), 1, null);
			Object obj = f.call(ctx, scope, scope, new Object[] { request, chain });
			if (obj instanceof Undefined) {
				return null;
			}
			Response ret = (Response) Context.jsToJava(obj, Response.class);
			return ret;
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			Context.exit();
		}
	}
}
